/*
 * Copyright © 2005 Novell, Inc.
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without
 * fee, provided that the above copyright notice appear in all copies
 * and that both that copyright notice and this permission notice
 * appear in supporting documentation, and that the name of
 * Novell, Inc. not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.
 * Novell, Inc. makes no representations about the suitability of this
 * software for any purpose. It is provided "as is" without express or
 * implied warranty.
 *
 * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Author: David Reveman <davidr@novell.com>
 */

#ifndef _COMPIZ_H
#define _COMPIZ_H

#include <stdio.h>
#include <sys/time.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/sync.h>
#include <X11/Xregion.h>
#include <X11/XKBlib.h>

#include <GL/gl.h>
#include <GL/glx.h>


/* Enable DF to view free() related messagges on console */
//# define DF(x)  do {printf(__FILE__ ":%d:  ", __LINE__); printf x; fflush(stdout);} while (0)
# define DF(x)  ((void) 0)

/* Colors for terminal debug */
#define C_OFF "\033[0m"
#define C_RED1 "\033[31;1m"
#define C_RED2 "\033[31;2m"
#define C_GRE1 "\033[32;1m"
#define C_GRE2 "\033[32;2m"
#define C_YEL1 "\033[33;1m"
#define C_YEL2 "\033[33;2m"
#define C_BLU1 "\033[34;1m"
#define C_BLU2 "\033[34;2m"
#define C_PUR1 "\033[35;1m"
#define C_PUR2 "\033[35;2m"
#define C_CYA1 "\033[36;1m"
#define C_CYA2 "\033[36;2m"
#define C_WHT1 "\033[37;1m"
#define C_WHT2 "\033[37;2m"

/*
 * WORDS_BIGENDIAN should be defined before including this file for
 * IMAGE_BYTE_ORDER and BITMAP_BIT_ORDER to be set correctly.
 */
#define LSBFirst 0
#define MSBFirst 1

#ifdef WORDS_BIGENDIAN
#  define IMAGE_BYTE_ORDER MSBFirst
#  define BITMAP_BIT_ORDER MSBFirst
#else
#  define IMAGE_BYTE_ORDER LSBFirst
#  define BITMAP_BIT_ORDER LSBFirst
#endif

typedef struct _CompPlugin  CompPlugin;
typedef struct _CompDisplay CompDisplay;
typedef struct _CompScreen  CompScreen;
typedef struct _CompWindow  CompWindow;
typedef struct _CompTexture CompTexture;
typedef struct _CompIcon    CompIcon;


#define OPAQUE 0xffff
#define COLOR  0xffff
#define BRIGHT 0xffff

#define RED_SATURATION_WEIGHT   0.30f
#define GREEN_SATURATION_WEIGHT 0.59f
#define BLUE_SATURATION_WEIGHT  0.11f

extern REGION     emptyRegion;
extern REGION     infiniteRegion;
extern GLushort   defaultColor[4];
extern Window     currentRoot;
extern CompWindow *lastFoundWindow;
extern CompWindow *lastDamagedWindow;
extern int        defaultRefreshRate;



/*****************************************************************************/
/****  privates.h  ***********************************************************/
/*****************************************************************************/

#define WRAP(priv, real, func, wrapFunc) \
    (priv)->func = (real)->func;	 \
    (real)->func = (wrapFunc)

#define UNWRAP(priv, real, func) \
    (real)->func = (priv)->func

typedef union _CompPrivate {
   void	  *ptr;
   long	  val;
   unsigned long uval;
   void	  *(*fptr) (void);
} CompPrivate;

typedef int (*ReallocPrivatesProc) (int size, void *closure);

int
allocatePrivateIndex (int		  *len,
                      char		  **indices,
                      ReallocPrivatesProc reallocProc,
                      void		  *closure);

void
freePrivateIndex (int  len,
                  char *indices,
                  int  index);

/*****************************************************************************/
/****  readpng.h  ************************************************************/
/*****************************************************************************/

Bool
openImageFile (const char *filename,
               char	  **returnFilename,
               FILE	  **returnFile);

Bool
readPng (const char   *filename,
         char	      **data,
         unsigned int *width,
         unsigned int *height);

Bool
readPngBuffer (const unsigned char *buffer,
               char		   **data,
               unsigned int	   *width,
               unsigned int	   *height);

/*****************************************************************************/
/****  display.h  ************************************************************/
/*****************************************************************************/

typedef Bool (*InitPluginForDisplayProc) (CompPlugin  *plugin,
                                          CompDisplay *display);

typedef void (*FiniPluginForDisplayProc) (CompPlugin  *plugin,
                                          CompDisplay *display);

//typedef void (*HandleEventProc) (CompDisplay *display,
//                                 XEvent      *event);


typedef void (*ForEachWindowProc) (CompWindow *window,
                                   void       *closure);

struct _CompDisplay {
   Display    *display;
   Eina_List  *screens;    /* CompScreen* (all the screen for this display) */

   char *screenPrivateIndices;
   int  screenPrivateLen;

   int compositeEvent, compositeError, compositeOpcode;
   int damageEvent, damageError;
   int randrEvent, randrError;
   int syncEvent, syncError;

   Bool shapeExtension;
   int  shapeEvent, shapeError;

   Atom workareaAtom;

   GLenum textureFilter;

   InitPluginForDisplayProc initPluginForDisplay;
   FiniPluginForDisplayProc finiPluginForDisplay;

   CompPrivate *privates;
};

int
allocateDisplayPrivateIndex (void);

void
freeDisplayPrivateIndex (int index);

void
addScreenToDisplay (CompDisplay *display,
                    CompScreen *s);

Bool
addDisplay (void);

void 
removeDisplay(CompDisplay *d);

void
forEachWindowOnDisplay (CompDisplay       *display,
                        ForEachWindowProc  proc,
                        void              *closure);

CompScreen *
findScreenAtDisplay (CompDisplay *d,
                     Window      root);

CompWindow *
findWindowAtDisplay (CompDisplay *display,
                     Window      id);

/*****************************************************************************/
/****  paint.h  **************************************************************/
/*****************************************************************************/

#define MULTIPLY_USHORT(us1, us2) \
    (((GLuint) (us1) * (GLuint) (us2)) / 0xffff)

/* camera distance from screen, 0.5 * tan (FOV) */
#define DEFAULT_Z_CAMERA 0.866025404f

typedef struct _ScreenPaintAttrib {
    GLfloat xRotate;
    GLfloat yRotate;
    GLfloat vRotate;
    GLfloat xTranslate;
    GLfloat yTranslate;
    GLfloat zTranslate;
    GLfloat zCamera;
} ScreenPaintAttrib;

typedef struct _WindowPaintAttrib {
    GLushort opacity;
    GLushort brightness;
    GLushort saturation;
    GLfloat  xScale;
    GLfloat  yScale;
} WindowPaintAttrib;

extern ScreenPaintAttrib defaultScreenPaintAttrib;
extern WindowPaintAttrib defaultWindowPaintAttrib;

typedef struct _CompMatrix {
    float xx; float yx;
    float xy; float yy;
    float x0; float y0;
} CompMatrix;

#define COMP_TEX_COORD_X(m, vx) ((m)->xx * (vx) + (m)->x0)
#define COMP_TEX_COORD_Y(m, vy) ((m)->yy * (vy) + (m)->y0)

#define COMP_TEX_COORD_XY(m, vx, vy) \
    ((m)->xx * (vx) + (m)->xy * (vy) + (m)->x0)
#define COMP_TEX_COORD_YX(m, vx, vy) \
    ((m)->yx * (vx) + (m)->yy * (vy) + (m)->y0)


typedef void (*PreparePaintScreenProc) (CompScreen *screen,
                                        int         msSinceLastPaint);

typedef void (*DonePaintScreenProc) (CompScreen *screen);

#define PAINT_SCREEN_REGION_MASK                   (1 << 0)
#define PAINT_SCREEN_FULL_MASK                     (1 << 1)
#define PAINT_SCREEN_TRANSFORMED_MASK              (1 << 2)
#define PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK (1 << 3)
#define PAINT_SCREEN_CLEAR_MASK                    (1 << 4)

typedef Bool (*PaintScreenProc) (CompScreen              *screen,
                                 const ScreenPaintAttrib *sAttrib,
                                 Region                   region,
                                 unsigned int             mask);

typedef void (*PaintTransformedScreenProc) (CompScreen              *screen,
                                            const ScreenPaintAttrib *sAttrib,
                                            unsigned int             mask);

#define PAINT_WINDOW_SOLID_MASK                 (1 << 0)
#define PAINT_WINDOW_TRANSLUCENT_MASK           (1 << 1)
#define PAINT_WINDOW_TRANSFORMED_MASK           (1 << 2)
#define PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK (1 << 3)

typedef Bool (*PaintWindowProc) (CompWindow              *window,
                                 const WindowPaintAttrib *attrib,
                                 Region                   region,
                                 unsigned int             mask);

typedef void (*AddWindowGeometryProc) (CompWindow *window,
                                       CompMatrix *matrix,
                                       int         nMatrix,
                                       Region      region,
                                       Region      clip);

typedef void (*DrawWindowTextureProc) (CompWindow              *w,
                                       CompTexture             *texture,
                                       const WindowPaintAttrib *attrib,
                                       unsigned int             mask);

typedef void (*DrawWindowGeometryProc) (CompWindow *window);

void
preparePaintScreen (CompScreen *screen,
                    int         msSinceLastPaint);

void
donePaintScreen (CompScreen *screen);

void
translateRotateScreen (const ScreenPaintAttrib *sa);

void
paintTransformedScreen (CompScreen              *screen,
                        const ScreenPaintAttrib *sAttrib,
                        unsigned int             mask);

Bool
paintScreen (CompScreen              *screen,
             const ScreenPaintAttrib *sAttrib,
             Region                   region,
             unsigned int             mask);

Bool
moreWindowVertices (CompWindow *w,
                    int         newSize);

void
addWindowGeometry (CompWindow *w,
                   CompMatrix *matrix,
                   int        nMatrix,
                   Region     region,
                   Region     clip);

void
drawWindowGeometry (CompWindow *w);

void
drawWindowTexture (CompWindow              *w,
                   CompTexture             *texture,
                   const WindowPaintAttrib *attrib,
                   unsigned int             mask);

Bool
paintWindow (CompWindow              *w,
             const WindowPaintAttrib *attrib,
             Region                   region,
             unsigned int             mask);

/*****************************************************************************/
/****  texture.h  ************************************************************/
/*****************************************************************************/

#define TEXTURE_STRICT_BINDING FALSE

#define POWER_OF_TWO(v) ((v & (v - 1)) == 0)

typedef enum {
   COMP_TEXTURE_FILTER_FAST,
   COMP_TEXTURE_FILTER_GOOD
} CompTextureFilter;

struct _CompTexture {
   GLuint     name;
   GLenum     target;
   GLfloat    dx, dy;
   GLXPixmap  pixmap;
   GLenum     filter;
   GLenum     wrap;
   CompMatrix matrix;
   Bool       oldMipmaps;
   Bool       mipmap;
};

void
initTexture (CompScreen  *screen,
             CompTexture *texture);

void
finiTexture (CompScreen  *screen,
             CompTexture *texture);

Bool
readImageToTexture (CompScreen   *screen,
                    CompTexture  *texture,
                    const char   *imageFileName,
                    unsigned int *width,
                    unsigned int *height);

Bool
readImageBufferToTexture (CompScreen          *screen,
                          CompTexture         *texture,
                          const unsigned char *imageBuffer,
                          unsigned int        *returnWidth,
                          unsigned int        *returnHeight);

Bool
iconToTexture (CompScreen *screen,
               CompIcon   *icon);

Bool
bindPixmapToTexture (CompScreen  *screen,
                     CompTexture *texture,
                     Pixmap       pixmap,
                     int          width,
                     int          height,
                     int          depth);

void
releasePixmapFromTexture (CompScreen  *screen,
                          CompTexture *texture);

void
enableTexture (CompScreen       *screen,
               CompTexture      *texture,
               CompTextureFilter filter);

void
disableTexture (CompScreen  *screen,
                CompTexture *texture);


/*****************************************************************************/
/****  screen.h  *************************************************************/
/*****************************************************************************/

#define SCREEN_DETECT_REFRESH_RATE  TRUE
#define SCREEN_LIGHTING             TRUE
#define SCREEN_UNREDIRECT_FS        FALSE //TODO DAVE //this go in paint.c ?
#define SCREEN_DEFAULT_ICON         "icon.png"
#define SCREEN_INDIRECT_RENDERING   TRUE

#ifndef GLX_EXT_texture_from_pixmap
#define GLX_BIND_TO_TEXTURE_RGB_EXT        0x20D0
#define GLX_BIND_TO_TEXTURE_RGBA_EXT       0x20D1
#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT     0x20D2
#define GLX_BIND_TO_TEXTURE_TARGETS_EXT    0x20D3
#define GLX_Y_INVERTED_EXT                 0x20D4
#define GLX_TEXTURE_FORMAT_EXT             0x20D5
#define GLX_TEXTURE_TARGET_EXT             0x20D6
#define GLX_MIPMAP_TEXTURE_EXT             0x20D7
#define GLX_TEXTURE_FORMAT_NONE_EXT        0x20D8
#define GLX_TEXTURE_FORMAT_RGB_EXT         0x20D9
#define GLX_TEXTURE_FORMAT_RGBA_EXT        0x20DA
#define GLX_TEXTURE_1D_BIT_EXT             0x00000001
#define GLX_TEXTURE_2D_BIT_EXT             0x00000002
#define GLX_TEXTURE_RECTANGLE_BIT_EXT      0x00000004
#define GLX_TEXTURE_1D_EXT                 0x20DB
#define GLX_TEXTURE_2D_EXT                 0x20DC
#define GLX_TEXTURE_RECTANGLE_EXT          0x20DD
#define GLX_FRONT_LEFT_EXT                 0x20DE
#endif

typedef void (*FuncPtr) (void);
typedef FuncPtr (*GLXGetProcAddressProc) (const GLubyte *procName);

typedef void    (*GLXBindTexImageProc)    (Display	 *display,
                  GLXDrawable   drawable,
                  int           buffer,
                  int          *attribList);
typedef void    (*GLXReleaseTexImageProc) (Display	 *display,
                  GLXDrawable   drawable,
                  int           buffer);
typedef void    (*GLXQueryDrawableProc)   (Display	 *display,
                  GLXDrawable   drawable,
                  int           attribute,
                  unsigned int *value);

typedef void (*GLXCopySubBufferProc) (Display     *display,
                  GLXDrawable drawable,
                  int     x,
                  int     y,
                  int     width,
                  int     height);

#ifndef GLX_VERSION_1_3
typedef struct __GLXFBConfigRec *GLXFBConfig;
#endif

typedef GLXFBConfig *(*GLXGetFBConfigsProc) (Display *display,
                     int     screen,
                     int     *nElements);
typedef int (*GLXGetFBConfigAttribProc) (Display     *display,
             GLXFBConfig config,
             int         attribute,
             int        *value);
typedef GLXPixmap (*GLXCreatePixmapProc) (Display     *display,
                   GLXFBConfig config,
                   Pixmap      pixmap,
                   const int   *attribList);

typedef void (*GLActiveTextureProc) (GLenum texture);
typedef void (*GLClientActiveTextureProc) (GLenum texture);

typedef void (*GLGenProgramsProc) (GLsizei n, GLuint  *programs);
typedef void (*GLDeleteProgramsProc) (GLsizei n, GLuint  *programs);
typedef void (*GLBindProgramProc) (GLenum target, GLuint program);
typedef void (*GLProgramStringProc) (GLenum	  target,
                                     GLenum	  format,
                                     GLsizei	  len,
                                     const GLvoid *string);
typedef void (*GLProgramLocalParameter4fProc) (GLenum  target,
                                               GLuint  index,
                                               GLfloat x,
                                               GLfloat y,
                                               GLfloat z,
                                               GLfloat w);

typedef void (*GLGenFramebuffersProc) (GLsizei n, GLuint  *framebuffers);
typedef void (*GLDeleteFramebuffersProc) (GLsizei n, GLuint  *framebuffers);
typedef void (*GLBindFramebufferProc) (GLenum target, GLuint framebuffer);
typedef GLenum (*GLCheckFramebufferStatusProc) (GLenum target);
typedef void (*GLFramebufferTexture2DProc) (GLenum target,
                                            GLenum attachment,
                                            GLenum textarget,
                                            GLuint texture,
                                            GLint  level);
typedef void (*GLGenerateMipmapProc) (GLenum target);

#define MAX_DEPTH 32

typedef Bool (*InitPluginForScreenProc) (CompPlugin *plugin,
                                         CompScreen *screen);

typedef void (*FiniPluginForScreenProc) (CompPlugin *plugin,
                                         CompScreen *screen);

typedef Bool (*DamageWindowRectProc) (CompWindow *w,
                                      Bool       initial,
                                      BoxPtr     rect);

typedef Bool (*DamageWindowRegionProc) (CompWindow *w,
                                        Region     region);

typedef void (*SetWindowScaleProc) (CompWindow *w,
                                    float      xScale,
                                    float      yScale);


#define COMP_SCREEN_DAMAGE_PENDING_MASK (1 << 0)
#define COMP_SCREEN_DAMAGE_REGION_MASK  (1 << 1)
#define COMP_SCREEN_DAMAGE_ALL_MASK     (1 << 2)


typedef struct _CompFBConfig {
    GLXFBConfig fbConfig;
    int         yInverted;
    int         mipmap;
    int         textureFormat;
} CompFBConfig;

#define NOTHING_TRANS_FILTER 0
#define SCREEN_TRANS_FILTER  1
#define WINDOW_TRANS_FILTER  2

typedef struct _CompScreenHead {
   int x, y, width, height, areaX, areaY, areaWidth, areaHeight;
} CompScreenHead;

struct _CompIcon {
   CompTexture texture;
   int         width;
   int         height;
};

struct _CompScreen {
   CompDisplay  *display;
   Eina_List    *windows;           /* CompWindow* list with all the solid wins*/

   char         *windowPrivateIndices;
   int           windowPrivateLen;

   Colormap      colormap;
   int           screenNum;
   int           width;
   int           height;
   int           size;
   REGION        region;
   Region        damage;
   unsigned long damageMask;
   Window        root;
   XWindowAttributes attrib;
   CompFBConfig  glxPixmapFBConfigs[MAX_DEPTH + 1];
   int           textureRectangle;
   int           textureNonPowerOfTwo;
   int           textureEnvCombine;
   int           textureEnvCrossbar;
   int           textureBorderClamp;
   GLint         maxTextureSize;
   int           fbo;
   int           fragmentProgram;
   int           maxTextureUnits;
   XRectangle    *exposeRects;
   int           sizeExpose;
   int           nExpose;
   unsigned int  pendingDestroys;
   unsigned int  mapNum;
  // unsigned int  activeNum;

   int overlayWindowCount;

   int filter[3];

   CompIcon *defaultIcon;

   Bool canDoSaturated;
   Bool canDoSlightlySaturated;

   int            rasterX;
   int            rasterY;
   Bool           pendingCommands;

   GLint stencilRef;

   Bool lighting;

   XRectangle workArea;

   GLXGetProcAddressProc    getProcAddress;
   GLXBindTexImageProc      bindTexImage;
   GLXReleaseTexImageProc   releaseTexImage;
   GLXQueryDrawableProc     queryDrawable;
   GLXCopySubBufferProc     copySubBuffer;
   GLXGetFBConfigsProc      getFBConfigs;
   GLXGetFBConfigAttribProc getFBConfigAttrib;
   GLXCreatePixmapProc      createPixmap;

   GLActiveTextureProc       activeTexture;
   GLClientActiveTextureProc clientActiveTexture;

   GLGenProgramsProc        genPrograms;
   GLDeleteProgramsProc     deletePrograms;
   GLBindProgramProc        bindProgram;
   GLProgramStringProc      programString;
   GLProgramLocalParameter4fProc programLocalParameter4f;

   GLGenFramebuffersProc        genFramebuffers;
   GLDeleteFramebuffersProc     deleteFramebuffers;
   GLBindFramebufferProc        bindFramebuffer;
   GLCheckFramebufferStatusProc checkFramebufferStatus;
   GLFramebufferTexture2DProc   framebufferTexture2D;
   GLGenerateMipmapProc         generateMipmap;

   GLXContext ctx;

   InitPluginForScreenProc initPluginForScreen;
   FiniPluginForScreenProc finiPluginForScreen;

   PreparePaintScreenProc       preparePaintScreen;
   DonePaintScreenProc          donePaintScreen;
   PaintScreenProc              paintScreen;
   PaintTransformedScreenProc   paintTransformedScreen;
   PaintWindowProc              paintWindow;
   AddWindowGeometryProc        addWindowGeometry;
   DrawWindowGeometryProc       drawWindowGeometry;
   DrawWindowTextureProc        drawWindowTexture;
   DamageWindowRectProc         damageWindowRect;
   SetWindowScaleProc           setWindowScale;

   CompPrivate *privates;

   Bool       useXinerama;
   int        headsCount;

   CompScreenHead *headsInfo;
};

int
allocateScreenPrivateIndex (CompDisplay *display);

void
freeScreenPrivateIndex (CompDisplay *display,
            int    index);

int 
screenGetHead ( CompScreen *s, int x, int y, int w, int h );

int
screenGetHeadForWindow ( CompWindow *w );

int
screenGetCurrentHead ( CompScreen *s );

int
screenGetHeadX ( CompScreen *s, int head );

int
screenGetHeadY ( CompScreen *s, int head );

int
screenGetHeadWidth ( CompScreen *s, int head );

int
screenGetHeadHeight ( CompScreen *s, int head );

int
screenGetHeadAreaX ( CompScreen *s, int head );

int
screenGetHeadAreaY ( CompScreen *s, int head );

int
screenGetHeadAreaWidth ( CompScreen *s, int head );

int
screenGetHeadAreaHeight ( CompScreen *s, int head );

Bool
addScreen (CompDisplay *display,
           int          screenNum,
           Window       root);

void 
removeScreen(CompScreen *s);

void
damageScreenRegion (CompScreen *screen,
                    Region      region);

void
damageScreen (CompScreen *screen);

void
damagePendingOnScreen (CompScreen *s);

void
insertWindowIntoScreen (CompScreen *s,
                        CompWindow *w,
                        Ecore_X_Window      aboveId);

void
unhookWindowFromScreen (CompScreen *s,
                        CompWindow *w);

void
forEachWindowOnScreen (CompScreen       *screen,
                       ForEachWindowProc proc,
                       void		       *closure);

CompWindow *
findWindowAtScreen (CompScreen *s,
                    Window     id);

void
updateWorkareaForScreen (CompScreen *s);

void
screenTexEnvMode (CompScreen *s,
                  GLenum     mode);

void
screenLighting (CompScreen *s,
                Bool       lighting);

Ecore_X_Window
getTopWindow (CompScreen *s);

void
makeScreenCurrent (CompScreen *s);

void
finishScreenDrawing (CompScreen *s);

/*****************************************************************************/
/****  window.h  *************************************************************/
/*****************************************************************************/

/*****************************************************************************/
/****  plugin.h  *************************************************************/
/*****************************************************************************/

typedef Bool (*InitPluginProc) (CompPlugin *plugin);
typedef void (*FiniPluginProc) (CompPlugin *plugin);

typedef Bool (*InitPluginForWindowProc) (CompPlugin *plugin,
                                         CompWindow *window);
typedef void (*FiniPluginForWindowProc) (CompPlugin *plugin,
                                         CompWindow *window);

typedef struct _CompPluginVTable {
   char *name;
   char *shortDesc;
   char *longDesc;

   InitPluginProc init;
   FiniPluginProc fini;

   InitPluginForDisplayProc initDisplay;
   FiniPluginForDisplayProc finiDisplay;

   InitPluginForScreenProc initScreen;
   FiniPluginForScreenProc finiScreen;

   InitPluginForWindowProc initWindow;
   FiniPluginForWindowProc finiWindow;
} CompPluginVTable;

typedef CompPluginVTable *(*PluginGetInfoProc) (void);

struct _CompPlugin {
   void             *dlhand;
   CompPluginVTable *vTable;
};

CompPluginVTable *
getCompPluginInfo (void);

void
screenInitPlugins (CompScreen *s);

void
screenFiniPlugins (CompScreen *s);

void
windowInitPlugins (CompWindow *w);

void
windowFiniPlugins (CompWindow *w);

//~ CompPlugin *
//~ findActivePlugin (char *name);

int
loadPlugins (char *path);

int
unloadPlugins (void);

/*****************************************************************************/
/****  lebang.h  *************************************************************/
/*****************************************************************************/




#endif /* _COMPIZ_H */

/* JUST FOR A QUICK REFERENCE ( E_Border )
struct _E_Border
{
   E_Object             e_obj_inherit;

   struct {
      struct {
         int x, y, w, h;
         int mx, my;
      } current, last_down[3], last_up[3];
   } mouse;

   struct {
      struct {
         int x, y, w, h;
         int mx, my;
         int button;
      } down;
   } moveinfo;

   Ecore_X_Window  win;
   int             x, y, w, h;
   int             ref;
   E_Zone         *zone;
   E_Desk         *desk;
   Eina_List      *handlers;

   struct {
      int          x, y;
      struct {
         int       x, y;
         double    t;
      } start;
   } fx;

   struct {
      int          l, r, t, b;
   } client_inset;

   Ecore_Evas     *bg_ecore_evas;
   Evas           *bg_evas;
   Ecore_X_Window  bg_win;
   Ecore_X_Window  bg_subwin;
   Evas_Object    *bg_object;
   Evas_Object    *icon_object;
   Ecore_X_Window  event_win;
   const char     *internal_icon;
   const char     *internal_icon_key;

   struct {
      Ecore_X_Window shell_win;
      Ecore_X_Window win;

      int x, y, w, h;

      struct {
         unsigned char changed : 1;
         unsigned char user_selected : 1;
         const char *name;
      } border;

      unsigned char shaped : 1;
      unsigned char argb : 1;
// ICCCM 
      struct {
         char *title;
         char *name;
         char *class;
         char *icon_name;
         char *machine;
         int min_w, min_h;
         int max_w, max_h;
         int base_w, base_h;
         int step_w, step_h;
         int start_x, start_y;
         double min_aspect, max_aspect;
         Ecore_X_Window_State_Hint initial_state;
         Ecore_X_Window_State_Hint state;
         Ecore_X_Pixmap icon_pixmap;
         Ecore_X_Pixmap icon_mask;
         Ecore_X_Window icon_window;
         Ecore_X_Window window_group;
         Ecore_X_Window transient_for;
         Ecore_X_Window client_leader;
         Ecore_X_Gravity gravity;
         char *window_role;
         unsigned char take_focus : 1;
         unsigned char accepts_focus : 1;
         unsigned char urgent : 1;
         unsigned char delete_request : 1;
         unsigned char request_pos : 1;
         struct {
            int argc;
            char **argv;
         } command;
         struct {
            unsigned char title : 1;
            unsigned char name_class : 1;
            unsigned char icon_name : 1;
            unsigned char machine : 1;
            unsigned char hints : 1;
            unsigned char size_pos_hints : 1;
            unsigned char protocol : 1;
            unsigned char transient_for : 1;
            unsigned char client_leader : 1;
            unsigned char window_role : 1;
            unsigned char state : 1;
            unsigned char command : 1;
         } fetch;
      } icccm;

// MWM
      struct {
         Ecore_X_MWM_Hint_Func func;
         Ecore_X_MWM_Hint_Decor decor;
         Ecore_X_MWM_Hint_Input input;
         unsigned char exists : 1;
         unsigned char borderless : 1;
         struct {
            unsigned char hints : 1;
         } fetch;
      } mwm;

// NetWM
      struct {
         pid_t         pid;
         unsigned int  desktop;
         char         *name;
         char         *icon_name;
         Ecore_X_Icon *icons;
         int           num_icons;
         unsigned int  user_time;
         struct {
            int left;
            int right;
            int top;
            int bottom;
            int left_start_y;
            int left_end_y;
            int right_start_y;
            int right_end_y;
            int top_start_x;
            int top_end_x;
            int bottom_start_x;
            int bottom_end_x;
         } strut;
         unsigned char ping : 1;
         struct {
            unsigned char        request : 1;
            unsigned int         wait;
            Ecore_X_Sync_Alarm   alarm;
            Ecore_X_Sync_Counter counter;
            unsigned int         serial;
            double               send_time;
         } sync;

// NetWM Window state 
         struct {
            unsigned char modal : 1;
            unsigned char sticky : 1;
            unsigned char maximized_v : 1;
            unsigned char maximized_h : 1;
            unsigned char shaded : 1;
            unsigned char skip_taskbar : 1;
            unsigned char skip_pager : 1;
            unsigned char hidden : 1;
            unsigned char fullscreen : 1;
            E_Stacking    stacking;
         } state;

// NetWM Window allowed actions 
         struct {
            unsigned char move : 1;
            unsigned char resize : 1;
            unsigned char minimize : 1;
            unsigned char shade : 1;
            unsigned char stick : 1;
            unsigned char maximized_h : 1;
            unsigned char maximized_v : 1;
            unsigned char fullscreen : 1;
            unsigned char change_desktop : 1;
            unsigned char close : 1;
         } action;

         Ecore_X_Window_Type type;
         int startup_id;

         struct {
            unsigned char name : 1;
            unsigned char icon_name : 1;
            unsigned char icon : 1;
            unsigned char user_time : 1;
            unsigned char strut : 1;
            unsigned char type : 1;
            unsigned char state : 1;
           
         } fetch;

         struct {
            unsigned char state : 1;
         } update;
      } netwm;

// Extra e stuff 
      struct {
         struct {
            unsigned char centered : 1;
         } state;

         struct {
            unsigned char state : 1;
         } fetch;
      } e;

      Ecore_X_Window_Attributes initial_attributes;
   } client;

     E_Container_Shape *shape;

   unsigned int    visible : 1;
   unsigned int    await_hide_event;
   unsigned int    moving : 1;
   unsigned int    focused : 1;
   unsigned int    new_client : 1;
   unsigned int    re_manage : 1;
   unsigned int    placed : 1;
   unsigned int    shading : 1;
   unsigned int    shaded : 1;
   unsigned int    iconic : 1;
   unsigned int    deskshow : 1;
   unsigned int    sticky : 1;
   unsigned int    shaped : 1;
   unsigned int    need_shape_merge : 1;
   unsigned int    need_shape_export : 1;
   unsigned int    fullscreen : 1;
   unsigned int    need_fullscreen : 1;
   unsigned int    already_unparented : 1;
   unsigned int    need_reparent : 1;
   unsigned int    button_grabbed : 1;
   unsigned int    delete_requested : 1;
   unsigned int    ping_ok : 1;
   unsigned int    hung : 1;
   unsigned int    take_focus : 1;
   unsigned int    want_focus : 1;
   unsigned int    user_skip_winlist : 1;
   unsigned int    need_maximize : 1;
   E_Maximize      maximized;
   unsigned int    borderless : 1;
   const char     *bordername;

   unsigned int    lock_user_location : 1; 
   unsigned int    lock_client_location : 1; 
   unsigned int    lock_user_size : 1; 
   unsigned int    lock_client_size : 1; 
   unsigned int    lock_user_stacking : 1; 
   unsigned int    lock_client_stacking : 1; 
   unsigned int    lock_user_iconify : 1; 
   unsigned int    lock_client_iconify : 1; 
   unsigned int    lock_user_desk : 1;
   unsigned int    lock_client_desk : 1;
   unsigned int    lock_user_sticky : 1; 
   unsigned int    lock_client_sticky : 1; 
   unsigned int    lock_user_shade : 1; 
   unsigned int    lock_client_shade : 1; 
   unsigned int    lock_user_maximize : 1; 
   unsigned int    lock_client_maximize : 1; 
   unsigned int    lock_user_fullscreen : 1; 
   unsigned int    lock_client_fullscreen : 1; 
   unsigned int    lock_border : 1; 
   unsigned int    lock_close : 1; 
   unsigned int    lock_focus_in : 1; 
   unsigned int    lock_focus_out : 1; 
   unsigned int    lock_life : 1; 
   unsigned int    internal : 1;

   Ecore_Evas     *internal_ecore_evas;

   double          ping;

   unsigned char   changed : 1;

   unsigned char   icon_preference;
   unsigned char   ignore_first_unmap;
   unsigned char   resize_mode;

     struct {
      int x, y, w, h;
      unsigned int layer;
      int zone;
   } saved;

   struct {
      unsigned char valid : 1;
      int x, y, w, h;
      struct {
         int x, y, w, h;
      } saved;
   } pre_res_change;

   struct {
      double start;
      double val;
      int x, y;
      E_Direction dir;
      Ecore_Animator *anim;
   } shade;

   struct {
      int x, y;
      int modified;
   } shelf_fix;

   Eina_List *stick_desks;
   E_Menu *border_menu;
   E_Config_Dialog *border_locks_dialog;
   E_Config_Dialog *border_remember_dialog;
   E_Config_Dialog *border_border_dialog;
   E_Dialog *border_prop_dialog;
   E_Menu *border_stacking_menu;
   E_Menu *border_maximize_menu;
   Eina_List *pending_move_resize;

   struct {
      unsigned char visible : 1;
      unsigned char pos : 1;
      unsigned char size : 1;
      unsigned char stack : 1;
      unsigned char prop : 1;
      unsigned char border : 1;
      unsigned char reset_gravity : 1;
      unsigned char shading : 1;
      unsigned char shaded : 1;
      unsigned char shape : 1;
      unsigned char icon : 1;
   } changes;

   struct {
      unsigned char start : 1;
      int x, y;
   } drag;


   unsigned int layer;
   E_Action *cur_mouse_action;
   Ecore_Timer *raise_timer;
   Ecore_Timer *ping_timer;
   Ecore_Timer *kill_timer;
   int shape_rects_num;
   Ecore_X_Rectangle *shape_rects;
   E_Remember *remember;

   E_Border *modal;

   E_Border  *leader;
   Eina_List *group;

   E_Border  *parent;
   Eina_List *transients;

   Efreet_Desktop *desktop;
   E_Pointer *pointer;

   unsigned char post_move   : 1;
   unsigned char post_resize : 1;
   unsigned char post_show : 1;
   Ecore_Idle_Enterer *post_job;
};


*/

/* JUST FOR A QUICK REFERENCE ( E_Event_Border )
typedef struct _E_Border                     E_Border;
typedef struct _E_Border_Pending_Move_Resize E_Border_Pending_Move_Resize;
typedef struct _E_Border_Hook                E_Border_Hook;
typedef struct _E_Event_Border_Simple        E_Event_Border_Resize;
typedef struct _E_Event_Border_Simple        E_Event_Border_Move;
typedef struct _E_Event_Border_Simple        E_Event_Border_Add;
typedef struct _E_Event_Border_Simple        E_Event_Border_Remove;
typedef struct _E_Event_Border_Simple        E_Event_Border_Show;
typedef struct _E_Event_Border_Simple        E_Event_Border_Hide;
typedef struct _E_Event_Border_Simple        E_Event_Border_Iconify;
typedef struct _E_Event_Border_Simple        E_Event_Border_Uniconify;
typedef struct _E_Event_Border_Simple        E_Event_Border_Stick;
typedef struct _E_Event_Border_Simple        E_Event_Border_Unstick;
typedef struct _E_Event_Border_Zone_Set      E_Event_Border_Zone_Set;
typedef struct _E_Event_Border_Desk_Set      E_Event_Border_Desk_Set;
typedef struct _E_Event_Border_Stack         E_Event_Border_Stack;
typedef struct _E_Event_Border_Simple        E_Event_Border_Icon_Change;
typedef struct _E_Event_Border_Simple        E_Event_Border_Urgent_Change;
typedef struct _E_Event_Border_Simple        E_Event_Border_Focus_In;
typedef struct _E_Event_Border_Simple        E_Event_Border_Focus_Out;
typedef struct _E_Event_Border_Simple        E_Event_Border_Property;
*/
